package utils

import (
	"archive/zip"
	"bytes"
	"encoding/binary"
	"hash/crc32"
	"io"
)

func IsZip(data []byte) bool {
	// ZIP 文件的文件头签名（magic number）
	const zipHeaderSignature uint32 = 0x04034b50

	// 确保数据长度足够
	if len(data) < 4 {
		return false
	}

	// 读取前 4 个字节并转换为小端格式的 uint32
	header := binary.LittleEndian.Uint32(data[:4])

	// 比较签名
	return header == zipHeaderSignature
}

func CompressZip(data []byte) ([]byte, error) {
	// 计算CRC32校验和
	crc32Checksum := crc32.ChecksumIEEE(data)
	crcLength := len(string(crc32Checksum))

	// 创建一个缓冲区来存储压缩后的数据
	buf := new(bytes.Buffer)

	// 创建一个新的zip writer
	zipWriter := zip.NewWriter(buf)

	// 创建一个新的zip entry
	entryName := string(len(data)) + "." + string(crcLength)
	entry, err := zipWriter.Create(entryName)
	if err != nil {
		return nil, err
	}

	// 将数据写入zip entry
	_, err = entry.Write(data)
	if err != nil {
		return nil, err
	}

	// 将CRC32校验和写入zip entry
	_, err = entry.Write([]byte(string(crc32Checksum)))
	if err != nil {
		return nil, err
	}

	// 关闭zip writer
	err = zipWriter.Close()
	if err != nil {
		return nil, err
	}

	// 返回压缩后的数据
	return buf.Bytes(), nil
}

func DecompressZip(compressedData []byte) ([]byte, error) {
	// 创建一个reader来读取压缩后的数据
	zipReader, err := zip.NewReader(bytes.NewReader(compressedData), int64(len(compressedData)))
	if err != nil {
		return nil, err
	}

	// 获取第一个entry
	entry := zipReader.File[0]

	// 打开entry
	entryReader, err := entry.Open()
	if err != nil {
		return nil, err
	}
	defer entryReader.Close()

	// 读取entry中的数据
	data, err := io.ReadAll(entryReader)
	if err != nil {
		return nil, err
	}

	// 返回解压缩后的数据
	return data, nil
}
